import React, { CSSProperties, Fragment } from 'react';
import { Modal } from 'antd';
import { ModalProps } from 'antd/es/modal';
import classNames from 'classnames';
import { DetailTable, DetailTableData, DetailTableProps } from './DetailTable';

interface DetailModalProps {
  // ----------------------------------------------------------------------------------- 初始值
  /** 初始化是否显示 */
  initVisible?: boolean;
  /** 详情表格数据 */
  initData?: DetailTableProps['initData'];
  // ----------------------------------------------------------------------------------- 核心配置
  /** 宽度 */
  modalWidth?: ModalProps['width'];
  /** 标题 */
  modalTitle?: ModalProps['title'];
  /** 底部内容 */
  modalFooter?: ModalProps['footer'];
  /** 每次显示之前都刷新数据 */
  refreshOnOpen?: boolean;
  /** 点击确定回调 */
  onOk?: ModalProps['onOk'];
  /** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调 */
  onCancel?: ModalProps['onCancel'];
  /** 确认按钮文字 */
  okText?: ModalProps['okText'];
  /** 取消按钮文字 */
  cancelText?: ModalProps['cancelText'];
  /** 点击蒙层是否允许关闭 */
  maskClosable?: ModalProps['maskClosable'];
  /** 对话框确定按钮属性 */
  okButtonProps?: ModalProps['okButtonProps'];
  /** 对话框取消按钮属性 */
  cancelButtonProps?: ModalProps['cancelButtonProps'];
  /** 详情表格列数 */
  columnCount: DetailTableProps['columnCount'];
  /** label配置(决定显示字段和排序) */
  labels: DetailTableProps['labels'];
  /** 数据转换配置 */
  dataTransforms?: DetailTableProps['dataTransforms'];
  /** label单元格宽度 */
  labelSpan: DetailTableProps['labelSpan'];
  /** 获取服务端数据配置 */
  serverData?: DetailTableProps['serverData'];
  /** 边框颜色 | "#e8e8e8" | "#d8ecfc" */
  borderColor?: DetailTableProps['borderColor'];
  /** 表头单元格背景颜色 | "#fafafa" | "#e7f1fa" */
  labelBackgroundColor?: DetailTableProps['labelBackgroundColor'];
  // ----------------------------------------------------------------------------------- 扩展配置
  /** 对话框属性 */
  modalProps?: Partial<ModalProps>;
  /** 详情表格属性 */
  detailTableProps?: Partial<DetailTableProps>;
  /** 自定义样式 */
  style?: CSSProperties;
  /** 自定义class样式 */
  className?: string;
}

interface DetailModalState {
  visible: boolean;
}

class DetailModal extends React.Component<DetailModalProps, DetailModalState> {
  static defaultProps: Readonly<Partial<DetailModalProps>> = {
    initVisible: false,
    initData: {},
    modalFooter: null,
    refreshOnOpen: false,
    cancelButtonProps: {
      style: { display: 'none' },
    },
  };

  protected detailTableRef: DetailTable | null = null;

  constructor(props: DetailModalProps) {
    super(props);
    const { initVisible = false } = props;
    this.state = {
      visible: initVisible,
    };
  }

  protected getModal(): React.ReactNode {
    const { visible } = this.state;
    const { initData, modalWidth, modalTitle, modalFooter, onOk, onCancel, okText, cancelText, maskClosable, okButtonProps, cancelButtonProps, modalProps } = this.props;
    const { columnCount, labels, dataTransforms, labelSpan, serverData, borderColor, labelBackgroundColor, detailTableProps, style, className } = this.props;
    return (
      <Modal
        visible={visible}
        width={modalWidth}
        title={modalTitle}
        footer={modalFooter}
        onOk={async (e) => {
          await this.setVisible(false);
          if (onOk instanceof Function) {
            onOk(e);
          }
        }}
        onCancel={async (e) => {
          await this.setVisible(false);
          if (onCancel instanceof Function) {
            onCancel(e);
          }
        }}
        okText={okText}
        cancelText={cancelText}
        maskClosable={maskClosable}
        okButtonProps={okButtonProps}
        cancelButtonProps={cancelButtonProps}
        style={style}
        className={classNames(className)}
        {...modalProps}
      >
        <DetailTable
          ref={(ref) => {
            this.detailTableRef = ref;
          }}
          initData={initData}
          columnCount={columnCount}
          labels={labels}
          dataTransforms={dataTransforms}
          labelSpan={labelSpan}
          serverData={serverData}
          borderColor={borderColor}
          labelBackgroundColor={labelBackgroundColor}
          {...detailTableProps}
          onLoadingChange={(loading) => {
            if (detailTableProps && detailTableProps.onLoadingChange instanceof Function) {
              detailTableProps.onLoadingChange(loading);
            }
          }}
        />
      </Modal>
    );
  }

  public render() {
    const { children } = this.props;
    return (
      <Fragment>
        {this.getModal()}
        {React.Children.count(children) > 0 && <span onClick={() => this.setVisible(true)}>{children}</span>}
      </Fragment>
    );
  }

  // -------------------------------------------------------------------------------------------------------------- 外部方法

  /**
   * 当前是否是正在加载中
   */
  public isLoading(): boolean {
    const { detailTableRef } = this;
    if (detailTableRef) return detailTableRef.isLoading();
    return false;
  }

  /**
   * 设置当前组件加载中状态
   */
  public setLoading(loading: boolean): void {
    const { detailTableRef } = this;
    if (detailTableRef) {
      detailTableRef.setLoading(loading);
    }
  }

  /**
   * 获取当前数据
   */
  public getData(): DetailTableData {
    const { detailTableRef } = this;
    if (detailTableRef) {
      return detailTableRef.getData();
    }
    return {};
  }

  /**
   * 设置显示的数据
   * @param data DetailTableData数据
   */
  public setData(data: DetailTableData): void {
    const { detailTableRef } = this;
    if (detailTableRef) {
      detailTableRef.setData(data);
    }
  }

  /**
   * 当前组件是否隐藏
   */
  public isShow(): boolean {
    const { detailTableRef } = this;
    if (detailTableRef) {
      return detailTableRef.isShow();
    }
    return false;
  }

  /**
   * 设置是否隐藏组件
   * @param show false=(display: none) | true=(display: unset)
   */
  public setShow(show: boolean): void {
    const { detailTableRef } = this;
    if (detailTableRef) {
      detailTableRef.setShow(show);
    }
  }

  /**
   * 重新加载数据(刷新数据)
   */
  public async refresh(): Promise<void> {
    const { detailTableRef } = this;
    if (detailTableRef) {
      await detailTableRef.refresh();
    }
  }

  /**
   * 获取 DetailTable 组件
   */
  public getDetailTable(): DetailTable | null {
    return this.detailTableRef;
  }

  /**
   * 当前对话框是否显示
   */
  public getVisible(): boolean {
    const { visible } = this.state;
    return visible;
  }

  /**
   * 设置对话框是否显示
   */
  public setVisible(visible: boolean): void {
    const { refreshOnOpen } = this.props;
    const { visible: oldVisible } = this.state;
    if (refreshOnOpen && !oldVisible && visible) {
      this.refresh().then();
    }
    this.setState({ visible });
  }
}

export { DetailModalProps, DetailModalState, DetailModal };
